Die Strings landen im Flash und RAM wenn man keine Dinge wie F() Makro und PROGMEM verwendet. Wenn ja, belegen sie nur Flash.
Der AVR hat eine modifizierte Harvard Architektur. Das heißt Flash und RAM haben getrennte Adress-Räume. Und der Befehlsatz arbeitet generell mit Adressen im RAM und Register-Bereich. Um auf Flash zuzugreifen gibt es auf Assembler-Ebene nur ein paar begrenzte Befehle die Daten aus dem Flash ins RAM kopieren. Der AVR gcc Compiler umgeht dieses Problem indem die Strings beim Programmstart aus dem Flash ins RAM kopiert werden.
Bei PROGMEM Verwendung wird wird insofern etwas mehr Flash belegt als dass man immer noch die Daten bei Bedarf ins RAM kopieren muss. Dadurch entsteht etwas mehr Code. Aber die Strings selbst belegen genauso Flash wie vorher auch.
Sieht so aus also ob die die Grenzen des UNOs erreicht hast. Bei beiden Speicher Arten. Der RAM Verbrauch liegt auch an der SD Lib. Die hat glaube ich einen 512kB Puffer für die Sektoren der Karte.
Beim RAM kann man nicht mehr viel machen, und wenn du 32k Flash erreicht hast ist es mit dem Optimieren sowieso größtenteils vorbei.