user76446: I suspect that I might be using too many resources, because of the strings, but I am new to Arduino, so not sure where I am going wrong.  Any help would be appreciated.
What it should do when complete:
"Birthday Reminder"

Read the SD card for a "birthday" file ("MM-DD.txt" ) that matches
"today".
The file contains the Name of the person and year of
birth.
Flash LED's and display the person's name and age on the
OLED.
The unit will not displayed anything until someone's birthday.

I am using the SD card with a simple format, to easily add new birthday's.
Output:
⸮Initializing SD card...
card initialized.
25
111
opening: 04-25.txt
2020"Test Person"
bYearStr: 20

The sd card file:
Name: MM-DD.txt 
Example: 04-25.txt 

Contents: Birthyear, Name 
Example: 2020"Test Person"

The Sketch
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"

RTC_DS3231 rtc;

int age;
int led;
int dly;
String bName;
String bYearStr;
int bYear;
int currentDay;
int  tDy;
int  tMth;
int  tYr;

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  Serial.begin(9600);
  delay(3000); // wait for console opening

  // Setup Candle pins
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.display(); // this command will display all the data which is in buffer
  display.setTextColor(WHITE, BLACK);

  const int SdCardPin = 10;
  Serial.println("Initializing SD card..."); // Verifying SD Card.
  //  if (!SD.begin(SdCardPin)) {
  if (!SD.begin(10)) {
    Serial.println("Card failed, or not present"); // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");

  currentDay = 111;
}


void loop() {
  age = 0;

  DateTime now = rtc.now();
  tDy = now.day();
  tMth = now.month();
  tYr = now.year();
  Serial.println(tDy);
  Serial.println(currentDay);

  if (currentDay != tDy) {
    String fileName;
    String m = String(tMth);
    String d = String(tDy);

    if (tMth < 10) {
      String mm = m;
      m = "0" + mm;
    }
    if (tDy < 10) {
      String dd = d;
      d =  "0" + dd;
    }
    fileName = m + "-" + d + ".txt";

    //String fileName = "01-01.txt";
    Serial.println("opening: " + fileName);
    File f = SD.open(fileName);
    delay(3000);

    if (!f) {
      Serial.println("open failed");
    } else {
      while (f.available()) {
        String line = f.readStringUntil('\n');
        Serial.println(line);
        bYearStr = line.substring(0, 4);
        bName = line.substring(4);
        delay(1000);
        currentDay = tDy;
        break;
      }
      f.close();
    }

    Serial.print("bYearStr: ");
    Serial.println(bYearStr);
    Serial.print("bName: ");
    Serial.println(bName);
    int bYear = bYearStr.toInt();
    age = tYr - bYear;
    Serial.print("Age: ");
    Serial.println(age);


  } else { // Start current day equal
    display.setTextSize(1);
    display.setCursor(38, 10);
    display.print("Birthday!");
    display.println();

    display.setTextSize(1);
    display.setCursor(0, 30);
    display.print("Name: ");
    display.print(bName);
    display.setCursor(0, 40);
    display.print("Age: ");
    display.print(age );
    display.println();

    led = random(3, 6);
    dly = random(80, 250);
    digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(dly);              // wait
    digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  } // End current day

  display.display();

} // End void Loop


user70020: It is quite likely you're out of memory. To know, really you need to keep track of the stack pointer and heap structure. There's enough going on in your code, that I'm not reasonably going to be able to set up an identical scenario to prove it.
Display Library
The greatest use of SRAM in your project comes from the Adafruit SSD1306 library.  It's allocating a buffer for the entire frame, which is 128 * 64 == 8192 bits, or 1024 bytes, half your Nano's SRAM.  It will use more than that for other data, though probably not a lot more by percentage.
You may be able to mitigate this usage with a library like trades some SRAM usage for extra execution time or lower frame rates.  One is the U8g2 library.  You can read about how it can use half-buffer in some documentation to the older version of the library; the concept carries over to the newer library.
SD Library
The next largest usage is the SD card libraries sector buffer, which is 512 bytes.
So between the two of them, there go 3/4 of your SRAM in just the two buffers, nevermind anything else.
You may be able to avoid this buffer by using a different library.  You could try PetitFS.  The library it wraps says it uses something like 44 bytes plus whatever call stack is needed.
String Literals
You have at least 206 bytes of string literals in your sketch alone, assuming the compiler can't determine that any of them are in fact unused.  There may be others in the libraries, though probably not many. So now we're down to at least 306 bytes or less SRAM.




Size
String




35
"RTC lost power, lets set the time!"


28
"Card failed, or not present"


24
"Initializing SD card..."


18
"Couldn't find RTC"


18
"card initialized."


12
"open failed"


11
"bYearStr: "


10
"opening: "


10
"Birthday!"


10
"01-01.txt"


8
"bName: "


7
"Name: "


6
"Age: "


5
".txt"


2
"-" 


2
"0"


206
Total




The "0" is only counted once in the above, even though you have two of them.  Fun fact: the C and C++ languages allow identical string literals to be colocated or overlap.  I don't know whether or not avr-gcc will combine "Name: " into "bName: ", since you have bigger problems to worry about, I'm just pretending it won't without looking.
Mitigation can include use of the F() macro to move some of these string literals into PROGMEM (flash).  You can't do this to every string literal, but the ones where you're involving them in a String(F("we're trying to avoid these right?")) constructor or in Serial (or other Stream/Print instances)'s .print(F("Hello World"));
The guts of the F() macro is another called PSTR(), which does the actual work of putting the string literal into PROGMEM.  F() tags the resulting pointer with a dummy type that is used in function overloading in Arduino libraries.  The only reason why I mention this is because below, you'll see me use PSTR to do the same thing, only with a function that belongs to avr-libc rather than Arduino.
Note when you're initializing a String object from a regular string literal, you're paying the SRAM cost twice for the lifetime of the String object.  One copy is in SRAM for the literal used to call the String constructor, the other copy is in the dynamic memory allocated to the String object.
String class
This was pointed out in the comments; and it's true that it's better to avoid them.  Although, I think not actually the greatest problem in your case.
I see you've avoided unnecessarily adding them together for Serial output and instead are using separate .print() calls, so you're ahead of the game there.
For your filename, mitigation could be using fixed size local char array and snprintf_P() to cobble together your filename, something like:
char filename[sizeof "MM-DD.txt"];
snprintf_P(
    filename, sizeof filename,
    PSTR("%02u-%02u.txt"),
    tMth, tDy
);

or if you wanted to avoid pulling the beast of printf into your sketch, assuming it's not already there, you could do something like:
const char filename[] = {
    '0' + tMth / 10,
    '0' + tMth % 10,
    '-',
    '0' + tDy  / 10,
    '0' + tDy  % 10,
    '.',
    't',
    'x',
    't',
    '\0'
};

Serial
What Serial?  Yup, I mean, there's not a lot you can do about it, but I bring it up because the last conservative figure above was 306 bytes, and we didn't try to account for the what String is doing in the heap at all.  Well Serial takes 157 bytes according to a simple test here, which makes sense, because on the UNO it has two ring buffers for transmit and receive that are 64 bytes in size each, half a dozen pointers for configuring hardware registers to use, and head and tail indices for those buffers.  There's also another 12 bytes that are used for HardWareSerial's vtable.
So that puts you down to conservatively 137 bytes of SRAM for well, everything else.
Everything Else
There's a lot not accounted for here. Your globals, the libraries globals, other vtables, the String data on the heap, and the stack.  Those are just the ones coming to mind.  I mean just the millis()/micros() counter variables and fract take 9 bytes.  If you really want to dig into the details here, besides looking at the stack pointer and heap structure, the avr-nm command run on your sketch's .elf file with its -D, -S, and --size-sort is helpful for locating global variable usage and similar things.

76446: <p>I suspect that I might be using too many resources, because of the strings, but I am new to Arduino, so not sure where I am going wrong.  Any help would be appreciated.</p>
<p>What it should do when complete:
&quot;Birthday Reminder&quot;</p>
<ul>
<li>Read the SD card for a &quot;birthday&quot; file (&quot;MM-DD.txt&quot; ) that matches
&quot;today&quot;.</li>
<li>The file contains the Name of the person and year of
birth.</li>
<li>Flash LED's and display the person's name and age on the
OLED.</li>
<li>The unit will not displayed anything until someone's birthday.</li>
</ul>
<p>I am using the SD card with a simple format, to easily add new birthday's.</p>
<pre><code>Output:
⸮Initializing SD card...
card initialized.
25
111
opening: 04-25.txt
2020&quot;Test Person&quot;
bYearStr: 20
</code></pre>
<p><strong>The sd card file:</strong></p>
<pre><code>Name: MM-DD.txt 
Example: 04-25.txt 

Contents: Birthyear, Name 
Example: 2020&quot;Test Person&quot;
</code></pre>
<p><strong>The Sketch</strong></p>
<pre><code>#include &lt;SPI.h&gt;
#include &lt;SD.h&gt;
#include &lt;Wire.h&gt;
#include &lt;Adafruit_GFX.h&gt;
#include &lt;Adafruit_SSD1306.h&gt;
#include &quot;RTClib.h&quot;

RTC_DS3231 rtc;

int age;
int led;
int dly;
String bName;
String bYearStr;
int bYear;
int currentDay;
int  tDy;
int  tMth;
int  tYr;

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &amp;Wire, OLED_RESET);

void setup() {
  Serial.begin(9600);
  delay(3000); // wait for console opening

  // Setup Candle pins
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  if (! rtc.begin()) {
    Serial.println(&quot;Couldn't find RTC&quot;);
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println(&quot;RTC lost power, lets set the time!&quot;);
    // following line sets the RTC to the date &amp; time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date &amp; time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.display(); // this command will display all the data which is in buffer
  display.setTextColor(WHITE, BLACK);

  const int SdCardPin = 10;
  Serial.println(&quot;Initializing SD card...&quot;); // Verifying SD Card.
  //  if (!SD.begin(SdCardPin)) {
  if (!SD.begin(10)) {
    Serial.println(&quot;Card failed, or not present&quot;); // don't do anything more:
    while (1);
  }
  Serial.println(&quot;card initialized.&quot;);

  currentDay = 111;
}


void loop() {
  age = 0;

  DateTime now = rtc.now();
  tDy = now.day();
  tMth = now.month();
  tYr = now.year();
  Serial.println(tDy);
  Serial.println(currentDay);

  if (currentDay != tDy) {
    String fileName;
    String m = String(tMth);
    String d = String(tDy);

    if (tMth &lt; 10) {
      String mm = m;
      m = &quot;0&quot; + mm;
    }
    if (tDy &lt; 10) {
      String dd = d;
      d =  &quot;0&quot; + dd;
    }
    fileName = m + &quot;-&quot; + d + &quot;.txt&quot;;

    //String fileName = &quot;01-01.txt&quot;;
    Serial.println(&quot;opening: &quot; + fileName);
    File f = SD.open(fileName);
    delay(3000);

    if (!f) {
      Serial.println(&quot;open failed&quot;);
    } else {
      while (f.available()) {
        String line = f.readStringUntil('\n');
        Serial.println(line);
        bYearStr = line.substring(0, 4);
        bName = line.substring(4);
        delay(1000);
        currentDay = tDy;
        break;
      }
      f.close();
    }

    Serial.print(&quot;bYearStr: &quot;);
    Serial.println(bYearStr);
    Serial.print(&quot;bName: &quot;);
    Serial.println(bName);
    int bYear = bYearStr.toInt();
    age = tYr - bYear;
    Serial.print(&quot;Age: &quot;);
    Serial.println(age);


  } else { // Start current day equal
    display.setTextSize(1);
    display.setCursor(38, 10);
    display.print(&quot;Birthday!&quot;);
    display.println();

    display.setTextSize(1);
    display.setCursor(0, 30);
    display.print(&quot;Name: &quot;);
    display.print(bName);
    display.setCursor(0, 40);
    display.print(&quot;Age: &quot;);
    display.print(age );
    display.println();

    led = random(3, 6);
    dly = random(80, 250);
    digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(dly);              // wait
    digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  } // End current day

  display.display();

} // End void Loop
</code></pre>
 70020: <p>It <em>is</em> quite likely you're out of memory. To know, really you need to keep track of the stack pointer and heap structure. There's enough going on in your code, that I'm not reasonably going to be able to set up an identical scenario to prove it.</p>
<h3>Display Library</h3>
<p>The greatest use of SRAM in your project comes from the Adafruit SSD1306 library.  It's <a href="https://github.com/adafruit/Adafruit_SSD1306/blob/2.4.4/Adafruit_SSD1306.cpp#L466" rel="nofollow noreferrer">allocating a buffer for the entire frame</a>, which is 128 * 64 == 8192 bits, or 1024 bytes, half your Nano's SRAM.  It will use more than that for other data, though probably not a lot more by percentage.</p>
<p>You may be able to mitigate this usage with a library like trades some SRAM usage for extra execution time or lower frame rates.  One is the <a href="https://github.com/olikraus/u8g2" rel="nofollow noreferrer">U8g2 library</a>.  You can read about <a href="https://github.com/olikraus/u8glib/wiki/tpictureloop" rel="nofollow noreferrer">how it can use half-buffer</a> in some documentation to the older version of the library; the concept carries over to the newer library.</p>
<h3>SD Library</h3>
<p>The next largest usage is the <a href="https://github.com/arduino-libraries/SD/blob/1.2.4/src/utility/SdFat.h#L465" rel="nofollow noreferrer">SD card libraries sector buffer</a>, which is 512 bytes.</p>
<p>So between the two of them, there go 3/4 of your SRAM in just the two buffers, nevermind anything else.</p>
<p>You may be able to avoid this buffer by using a different library.  You could try <a href="https://github.com/greiman/PetitFS" rel="nofollow noreferrer">PetitFS</a>.  The library it wraps <a href="http://elm-chan.org/fsw/ff/00index_p.html" rel="nofollow noreferrer">says it uses something like 44 bytes</a> plus whatever call stack is needed.</p>
<h3>String Literals</h3>
<p>You have at least 206 bytes of string literals in your sketch alone, assuming the compiler can't determine that any of them are in fact unused.  There <em>may</em> be others in the libraries, though probably not many. So now we're down to at least 306 bytes or less SRAM.</p>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>Size</th>
<th>String</th>
</tr>
</thead>
<tbody>
<tr>
<td>35</td>
<td><code>&quot;RTC lost power, lets set the time!&quot;</code></td>
</tr>
<tr>
<td>28</td>
<td><code>&quot;Card failed, or not present&quot;</code></td>
</tr>
<tr>
<td>24</td>
<td><code>&quot;Initializing SD card...&quot;</code></td>
</tr>
<tr>
<td>18</td>
<td><code>&quot;Couldn't find RTC&quot;</code></td>
</tr>
<tr>
<td>18</td>
<td><code>&quot;card initialized.&quot;</code></td>
</tr>
<tr>
<td>12</td>
<td><code>&quot;open failed&quot;</code></td>
</tr>
<tr>
<td>11</td>
<td><code>&quot;bYearStr: &quot;</code></td>
</tr>
<tr>
<td>10</td>
<td><code>&quot;opening: &quot;</code></td>
</tr>
<tr>
<td>10</td>
<td><code>&quot;Birthday!&quot;</code></td>
</tr>
<tr>
<td>10</td>
<td><code>&quot;01-01.txt&quot;</code></td>
</tr>
<tr>
<td>8</td>
<td><code>&quot;bName: &quot;</code></td>
</tr>
<tr>
<td>7</td>
<td><code>&quot;Name: &quot;</code></td>
</tr>
<tr>
<td>6</td>
<td><code>&quot;Age: &quot;</code></td>
</tr>
<tr>
<td>5</td>
<td><code>&quot;.txt&quot;</code></td>
</tr>
<tr>
<td>2</td>
<td><code>&quot;-&quot; </code></td>
</tr>
<tr>
<td>2</td>
<td><code>&quot;0&quot;</code></td>
</tr>
<tr>
<td>206</td>
<td><em>Total</em></td>
</tr>
</tbody>
</table>
</div>
<p>The <code>&quot;0&quot;</code> is only counted once in the above, even though you have two of them.  <em>Fun fact: the C and C++ languages allow identical string literals to be colocated or overlap.  I don't know whether or not avr-gcc will combine <code>&quot;Name: &quot;</code> into <code>&quot;bName: &quot;</code>, since you have bigger problems to worry about, I'm just pretending it won't without looking.</em></p>
<p>Mitigation can include <a href="https://www.arduino.cc/reference/en/language/variables/utilities/progmem/" rel="nofollow noreferrer">use of the <code>F()</code> macro</a> to move some of these string literals into PROGMEM (flash).  You can't do this to every string literal, but the ones where you're involving them in a <code>String(F(&quot;we're trying to avoid these right?&quot;))</code> constructor or in Serial (or other Stream/Print instances)'s <code>.print(F(&quot;Hello World&quot;));</code></p>
<p>The guts of the <code>F()</code> macro is another called <code>PSTR()</code>, which does the actual work of putting the string literal into PROGMEM.  <code>F()</code> tags the resulting pointer with a dummy type that is used in function overloading in Arduino libraries.  The only reason why I mention this is because below, you'll see me use <code>PSTR</code> to do the same thing, only with a function that belongs to avr-libc rather than Arduino.</p>
<p>Note when you're initializing a <code>String</code> object from a regular string literal, you're paying the SRAM cost twice for the lifetime of the <code>String</code> object.  One copy is in SRAM for the literal used to call the String constructor, the other copy is in the dynamic memory allocated to the String object.</p>
<h2>String class</h2>
<p>This was pointed out in the comments; and it's true that it's better to avoid them.  Although, I think not actually the greatest problem in your case.</p>
<p>I see you've avoided unnecessarily adding them together for Serial output and instead are using separate <code>.print()</code> calls, so you're ahead of the game there.</p>
<p>For your filename, mitigation could be using fixed size local <code>char</code> array and <code>snprintf_P()</code> to cobble together your filename, something like:</p>
<pre class="lang-cpp prettyprint-override"><code>char filename[sizeof &quot;MM-DD.txt&quot;];
snprintf_P(
    filename, sizeof filename,
    PSTR(&quot;%02u-%02u.txt&quot;),
    tMth, tDy
);
</code></pre>
<p>or if you wanted to avoid pulling the beast of <code>printf</code> into your sketch, assuming it's not already there, you could do something like:</p>
<pre class="lang-cpp prettyprint-override"><code>const char filename[] = {
    '0' + tMth / 10,
    '0' + tMth % 10,
    '-',
    '0' + tDy  / 10,
    '0' + tDy  % 10,
    '.',
    't',
    'x',
    't',
    '\0'
};
</code></pre>
<h2>Serial</h2>
<p>What <code>Serial</code>?  Yup, I mean, there's not a lot you can do about it, but I bring it up because the last conservative figure above was 306 bytes, and we didn't try to account for the what String is doing in the heap at all.  Well Serial takes 157 bytes according to a simple test here, which makes sense, because on the UNO it has two ring buffers for transmit and receive that are 64 bytes in size each, half a dozen pointers for configuring hardware registers to use, and head and tail indices for those buffers.  There's also another 12 bytes that are used for HardWareSerial's vtable.</p>
<p>So that puts you down to conservatively 137 bytes of SRAM for well, everything else.</p>
<h3>Everything Else</h3>
<p>There's a lot not accounted for here. Your globals, the libraries globals, other vtables, the String data on the heap, and the stack.  Those are just the ones coming to mind.  I mean just the <code>millis()</code>/<code>micros()</code> counter variables and fract take 9 bytes.  If you really want to dig into the details here, besides looking at the stack pointer and heap structure, the <code>avr-nm</code> command run on your sketch's .elf file with its <code>-D</code>, <code>-S</code>, and <code>--size-sort</code> is helpful for locating global variable usage and similar things.</p>
