Dovresti vedere il log e capire esattamente perché l'ESP32 va in eccezione.
Più che l'utilizzo delle String in se, che su ESP32 non è un gran problema per via della notevole quantità di RAM disponibile (520Kb), è l'utilizzo che ne fai ad essere piuttosto "strano" e potenzialmente "pericoloso".
Utilizzi una variabile globale ( String message;) nella funzione dove poi ritorni la variabile globale stessa come risultato e che assegni ad un ulteriore variabile globale (String readings;) ... è un non sense!
La variabile l'hai già modificata, a che serve tutto 'sto giro inutile? Invia direttamente la variabile message!
Questo modo di concatenare le stringhe è sconsigliabile perché frammenta molto facilmente l'heap.
message += "Temp min: " + String (temp_min) + " ºC \n\n";
// Sarebbe meglio se diventa (più lungo, ma più "safe")
message += "Temp min: ";
message += temp_min;
message += " ºC \n\n";
Inoltre usi delle librerie inutili o meglio non strettamente necessarie come quella per il tempo NTP che è già egregiamente gestita dal core ESP e non servono cose esterne.
Anche i delay piuttosto lunghi non sono una buona idea... Se la libreria per Telegram (che è bloccante) ci mette un po' con connessione/ricezione/invio e poi sommi il tempo del delay() è facile arrivare ad attivare il watchdog.