Necesito ayuda para que este codigo ocupe menos memoria... Quien me puede ayudar?

#include <SPI.h> // incluye libreria bus SPI
#include <MFRC522.h> // incluye libreria especifica para MFRC522
#include <SD.h> // for the SD card
#include <RTClib.h> // for the RTC
//#include <LiquidCrystal_I2C.h> //Downlaod the library: i2c Liquid crystal library for Arduino
//LiquidCrystal_I2C lcd(0x27,16,2);
#define RST_PIN 9 // constante para referenciar pin de reset
#define SS_PIN 10 // constante para referenciar pin de slave select
MFRC522 mfrc522(SS_PIN, RST_PIN); // crea objeto mfrc522 enviando pines de slave select y reset
#define CS_SD 4
#define buzzer 3
#define ledrojo A0
#define ledverde A2
#define ledazul A3
#define rele 5
File myFile;
RTC_DS3231 rtc; // crea objeto del tipo RTC_DS3231
const byte Usuario[20][4] ={
{0xCD, 0x7A, 0xD8, 0x01},
{0x06, 0x3B, 0xEE, 0xF9},
{0x79, 0xAB, 0xFC, 0x5C},
{0x2B, 0x1D, 0x31, 0x09},
{0x66, 0xD8, 0xDD, 0xF9},
{0x96, 0x0A, 0xBB, 0xEF}, //Prof. Jesus Tomases
{0xE8, 0xCC, 0x58, 0x0D},
{0xC3, 0x5E, 0xEF, 0xB6},
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00}
};
byte LecturaUID[4]; // crea array para almacenar el UID leido

String Docente;
const char docente_1[] PROGMEM = "Prof. Jorge Royero";
const char docente_2[] PROGMEM = "Prof. Albey Mejia";
const char docente_3[] PROGMEM = "Prof. Selfy De Los Reyes";
const char docente_4[] PROGMEM = "Prof. Giovany Peña";
const char docente_5[] PROGMEM = "Prof. Paola Guevara";
const char docente_6[] PROGMEM = "Prof. Jesus Tomases";
const char docente_7[] PROGMEM = "Prof. Fredy Charris";
const char docente_8[] PROGMEM = "Prof. Alberto Malagon";
const char docente_9[] PROGMEM = "Prof. Guillermina Garcia";
const char docente_10[] PROGMEM = "Prof. Jose Contreras";
const char docente_11[] PROGMEM = "Prof. Kely Tovar";
const char docente_12[] PROGMEM = "Prof. Alexandra Salazar";
const char docente_13[] PROGMEM = "Prof. ";
const char docente_14[] PROGMEM = "Prof. ";
const char docente_15[] PROGMEM = "Prof. ";
const char docente_16[] PROGMEM = "Prof. ";
const char docente_17[] PROGMEM = "Prof. ";
const char docente_18[] PROGMEM = "Prof. ";
const char docente_19[] PROGMEM = "Prof. ";
const char docente_20[] PROGMEM = "Prof. ";
const char docente_21[] PROGMEM = "Prof. ";
const char docente_22[] PROGMEM = "Prof. ";
const char docente_23[] PROGMEM = "Prof. ";
const char docente_24[] PROGMEM = "Prof. ";
const char docente_25[] PROGMEM = "Prof. ";
const char docente_26[] PROGMEM = "Prof. ";
const char docente_27[] PROGMEM = "Prof. ";
const char docente_28[] PROGMEM = "Prof. ";
const char docente_29[] PROGMEM = "Prof. ";
const char docente_30[] PROGMEM = "Prof. ";
const char* const names[] PROGMEM = {
docente_1, docente_2, docente_3, docente_4, docente_5, docente_6,
docente_7, docente_8, docente_9, docente_10, docente_11, docente_12,
docente_13, docente_14, docente_15, docente_16, docente_17, docente_18,
docente_19, docente_20, docente_21, docente_22, docente_23, docente_24,
docente_25, docente_26, docente_27, docente_28, docente_29, docente_30
};

#include <Keypad_I2C.h>
#include <Keypad.h> // GDY120705
#include <Wire.h>
#define I2CADDR 0x20
const byte ROWS = 4; //four rows
const byte COLS = 3; //four columns
char hexaKeys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
//byte rowPins[ROWS] = {0, 1, 2, 3}; //PARA KEYPAD 4X3 PLANO P0=F1, P1=F2, P2=F3, P3=F4
//byte colPins[COLS] = {4, 5, 6}; //PARA KEYPAD 4X3 PLANO P4=C1, P5=C2, P6=C3
byte rowPins[ROWS] = {1, 6, 5, 3}; //PARA KEYPAD 4X3 VOLUMETRICO P1=F1, P6=F2, P5=F3, P3=F4
byte colPins[COLS] = {2, 0, 4}; //PARA KEYPAD 4X3 VOLUMETRICO P2=C1, P0=C2, P4=C3

//initialize an instance of class NewKeypad
Keypad_I2C customKeypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS, I2CADDR);

char TECLA; // almacena la tecla presionada
char CLAVE[5]; // almacena en un array 4 digitos ingresados
char CLAVE_MAESTRA[5] = "8888"; // almacena en un array la contraseña maestra
char USUARIO1[5] = "1231"; // JORGE ROYERO
char USUARIO2[5] = "1232"; // JARED
char USUARIO3[5] = "1233"; // SELFY
char USUARIO4[5] = "1234"; // KENDRY
char USUARIO5[5] = "1235"; //
char USUARIO6[5] = "1236"; //
char USUARIO7[5] = "1237"; //
char USUARIO8[5] = "1238"; //
char USUARIO9[5] = "1239"; //
char USUARIO10[5] = "1240"; //
char USUARIO11[5] = "1241"; //
char USUARIO12[5] = "1242";
char USUARIO13[5] = "1243"; //
char USUARIO14[5] = "1244"; //
char USUARIO15[5] = "1245"; //
char USUARIO16[5] = "1246"; //
char USUARIO17[5] = "1247"; //
char USUARIO18[5] = "1248"; //
char USUARIO19[5] = "1249"; //
char USUARIO20[5] = "1250";
char USUARIO21[5] = "1251"; //
char USUARIO22[5] = "1252";
char USUARIO23[5] = "1253"; //
char USUARIO24[5] = "1254"; //
char USUARIO25[5] = "1255"; //
char USUARIO26[5] = "1256"; //
char USUARIO27[5] = "1257"; //
char USUARIO28[5] = "1258"; //
char USUARIO29[5] = "1259"; //
char USUARIO30[5] = "1260";

byte INDICE = 0; // indice del array

void setup() {
Serial.begin(9600); // inicializa comunicacion por monitor serie a 9600 bps
Wire.begin( ); // GDY200622
customKeypad.begin( ); // GDY120705
//lcd.init();
//lcd.backlight();
//lcd.setCursor(0,0);
//lcd.print("Coloque Tarjeta..");
pinMode(buzzer, OUTPUT);
pinMode(ledrojo, OUTPUT);
pinMode(ledverde, OUTPUT);
pinMode(ledazul, OUTPUT);
pinMode(rele, OUTPUT);
digitalWrite (buzzer, LOW);
digitalWrite (ledrojo, LOW);
digitalWrite (ledverde, LOW);
digitalWrite (ledazul, LOW);
digitalWrite (rele, LOW);

SPI.begin(); // inicializa bus SPI
mfrc522.PCD_Init(); // inicializa modulo lector
Serial.println("Listo"); // Muestra texto Listo

Serial.print("Initializing SD card...");
if(!SD.begin(CS_SD)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
// Setup for the RTC
if(!rtc.begin()) {
Serial.println("Couldn't find RTC");
while(1);
}
}

void loop() {
LeerTeclado();
if ( ! mfrc522.PICC_IsNewCardPresent()) // si no hay una tarjeta presente
return; // retorna al loop esperando por una tarjeta

if ( ! mfrc522.PICC_ReadCardSerial()) // si no puede obtener datos de la tarjeta
return; // retorna al loop esperando por otra tarjeta
Serial.print("UID:"); // muestra texto UID:

for (byte i = 0; i < mfrc522.uid.size; i++) {	// bucle recorre de a un byte por vez el UID
  if (mfrc522.uid.uidByte[i] < 0x10){		// si el byte leido es menor a 0x10
    Serial.print(" 0");				// imprime espacio en blanco y numero cero
    }
    else{						// sino
      Serial.print(" ");				// imprime un espacio en blanco
      }
      Serial.print(mfrc522.uid.uidByte[i], HEX);   	// imprime el byte del UID leido en hexadecimal
      LecturaUID[i]=mfrc522.uid.uidByte[i];   	// almacena en array el byte del UID leido      
       }
      Serial.print("\t");   			// imprime un espacio de tabulacion  

      for(int i = 0; i<10; i++){
       if(comparaUID(LecturaUID, Usuario[i])){		// llama a funcion comparaUID con Usuario1
        char arrayBuf[20];  // crea un búfer
        strcpy_P(arrayBuf, pgm_read_word(&(names[i])));
        Docente = arrayBuf;
        Serial.print("Bienvenido ");	// si retorna verdadero muestra texto bienvenida
        Serial.println(Docente);
        GrabarSdrfid();
        delay(30);
       }
        else						// si retorna falso
        Serial.println("No te conozco"); 		// muestra texto equivalente a acceso denegado          
        
        mfrc522.PICC_HaltA();  		// detiene comunicacion con tarjeta
      }           

} //AQUI FINALIZA EL LOOP

boolean comparaUID(byte lectura[],byte usuario[]) // funcion comparaUID
{
for (byte i=0; i < mfrc522.uid.size; i++){ // bucle recorre de a un byte por vez el UID
if(lectura[i] != usuario[i]) // si byte de UID leido es distinto a usuario
return(false); // retorna falso
}
return(true); // si los 4 bytes coinciden retorna verdadero
}

void GrabarSdrfid(){
digitalWrite(CS_SD,LOW); // Enables SD card chip select pin
myFile=SD.open("DATA.txt", FILE_WRITE);
if (myFile) {
delay(300);
//myFile.print(LecturaUID);
//myFile.print(", ");
DateTime now = rtc.now();
myFile.print(now.year(), DEC);
myFile.print('/');
myFile.print(now.month(), DEC);
myFile.print('/');
myFile.print(now.day(), DEC);
myFile.print(',');
myFile.print(now.hour(), DEC);
myFile.print(':');
myFile.print(now.minute(), DEC);
myFile.print(':');
myFile.print(now.second(), DEC);
myFile.print(',');
myFile.print(Docente); //Nomre del docente
myFile.print(',');
myFile.println("Acceso mediante chip RFID");
/*
Serial.print("Tag UID: ");
Serial.print("\t"); // imprime un espacio de tabulacion
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print("\t"); // imprime un espacio de tabulacion
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.print("\t"); // imprime un espacio de tabulacion
Serial.println(Docente); //Muestra el nombre del docente
*/
Serial.println("sucessfully written on SD card");
delay(300);
myFile.close();
Buzzer();
}
else {
Serial.println("error opening data.txt");
}
digitalWrite(CS_SD,HIGH); // Disables SD card chip select pin
}

void Buzzer(){
digitalWrite(buzzer,HIGH); 
digitalWrite (ledrojo, LOW);
digitalWrite (ledverde, HIGH);
digitalWrite (ledazul, LOW);
delay (100);
digitalWrite(buzzer,LOW);
delay (100);
digitalWrite(buzzer,HIGH);  
delay (100);
digitalWrite(buzzer,LOW);
digitalWrite (ledverde, LOW);

}

void BuzzerE(){
digitalWrite(buzzer,HIGH);
digitalWrite (ledrojo, HIGH);
digitalWrite (ledverde, LOW);
digitalWrite (ledazul, LOW);
delay (1000);
digitalWrite(buzzer,LOW);
digitalWrite (ledrojo, LOW);
}
void LeerTeclado(){

TECLA = customKeypad.getKey(); // obtiene tecla presionada y asigna a variable
if (TECLA) // comprueba que se haya presionado una tecla
{
CLAVE[INDICE] = TECLA; // almacena en array la tecla presionada
INDICE++; // incrementa indice en uno
Serial.print(TECLA); // envia a monitor serial la tecla presionada
}

if(INDICE == 4) // si ya se almacenaron los 4 digitos
{
Serial.print("\t"); // imprime un espacio de tabulacion
Serial.print("\t"); // imprime un espacio de tabulacion
Serial.print("\t"); // imprime un espacio de tabulacion
if(!strcmp(CLAVE, CLAVE_MAESTRA)){ // compara clave ingresada con clave maestra
Serial.println(" Correcta"); // imprime en monitor serial que es correcta la clave
delay (50);
}
else if(!strcmp(CLAVE, USUARIO1)){ // compara clave ingresada con clave maestra

  char arrayBuf[20];  // crea un búfer
  strcpy_P(arrayBuf, pgm_read_word(&(names[0])));
  Docente = arrayBuf;
  DateTime fecha = rtc.now();				// funcion que devuelve fecha y horario en formato
  //Serial.print("Hola ");
  //Serial.println(Docente);
  GrabarSdkeypad();//INICIA PROCESO DE ESCRITURA EN LA SD
}
else if(!strcmp(CLAVE, USUARIO2)){   // compara clave ingresada con clave maestra
  char arrayBuf[20];  // crea un búfer
  strcpy_P(arrayBuf, pgm_read_word(&(names[1])));
  Docente = arrayBuf;
  DateTime fecha = rtc.now();				// funcion que devuelve fecha y horario en formato
  //Serial.print("Hola ");
  //Serial.println(Docente);
  GrabarSdkeypad();//INICIA PROCESO DE ESCRITURA EN LA SD
}
else if(!strcmp(CLAVE, USUARIO3)){   // compara clave ingresada con clave maestra
  char arrayBuf[20];  // crea un búfer
  strcpy_P(arrayBuf, pgm_read_word(&(names[2])));
  Docente = arrayBuf;
  DateTime fecha = rtc.now();				// funcion que devuelve fecha y horario en formato
  //Serial.print("Hola ");
  //Serial.println(Docente);
  GrabarSdkeypad();//INICIA PROCESO DE ESCRITURA EN LA SD
}
else if(!strcmp(CLAVE, USUARIO4)){   // compara clave ingresada con clave maestra
  char arrayBuf[20];  // crea un búfer
  strcpy_P(arrayBuf, pgm_read_word(&(names[3])));
  Docente = arrayBuf;
  DateTime fecha = rtc.now();				// funcion que devuelve fecha y horario en formato
  //Serial.print("Hola ");
  //Serial.println(Docente);
  GrabarSdkeypad();//INICIA PROCESO DE ESCRITURA EN LA SD
}
else if(!strcmp(CLAVE, USUARIO5)){   // compara clave ingresada con clave maestra
  char arrayBuf[20];  // crea un búfer
  strcpy_P(arrayBuf, pgm_read_word(&(names[4])));
  Docente = arrayBuf;
  DateTime fecha = rtc.now();				// funcion que devuelve fecha y horario en formato
  //Serial.print("Hola ");
  //Serial.println(Docente);
  GrabarSdkeypad();//INICIA PROCESO DE ESCRITURA EN LA SD
}
else if(!strcmp(CLAVE, USUARIO6)){   // compara clave ingresada con clave maestra
  char arrayBuf[20];  // crea un búfer
  strcpy_P(arrayBuf, pgm_read_word(&(names[5])));
  Docente = arrayBuf;
  DateTime fecha = rtc.now();				// funcion que devuelve fecha y horario en formato
  //Serial.print("Hola ");
  //Serial.println(Docente);
  GrabarSdkeypad();//INICIA PROCESO DE ESCRITURA EN LA SD
}
else if(!strcmp(CLAVE, USUARIO7)){   // compara clave ingresada con clave maestra
  char arrayBuf[20];  // crea un búfer
  strcpy_P(arrayBuf, pgm_read_word(&(names[6])));
  Docente = arrayBuf;
  DateTime fecha = rtc.now();				// funcion que devuelve fecha y horario en formato
  //Serial.print("Hola ");
  //Serial.println(Docente);
  GrabarSdkeypad();//INICIA PROCESO DE ESCRITURA EN LA SD
}
else if(!strcmp(CLAVE, USUARIO8)){   // compara clave ingresada con clave maestra
  char arrayBuf[20];  // crea un búfer
  strcpy_P(arrayBuf, pgm_read_word(&(names[7])));
  Docente = arrayBuf;
  DateTime fecha = rtc.now();				// funcion que devuelve fecha y horario en formato
  //Serial.print("Hola ");
  //Serial.println(Docente);
  GrabarSdkeypad();//INICIA PROCESO DE ESCRITURA EN LA SD
}
else if(!strcmp(CLAVE, USUARIO9)){   // compara clave ingresada con clave maestra
  char arrayBuf[20];  // crea un búfer
  strcpy_P(arrayBuf, pgm_read_word(&(names[8])));
  Docente = arrayBuf;
  DateTime fecha = rtc.now();				// funcion que devuelve fecha y horario en formato
  //Serial.print("Hola ");
  //Serial.println(Docente);
  GrabarSdkeypad();//INICIA PROCESO DE ESCRITURA EN LA SD
}
else if(!strcmp(CLAVE, USUARIO10)){   // compara clave ingresada con clave maestra
  char arrayBuf[20];  // crea un búfer
  strcpy_P(arrayBuf, pgm_read_word(&(names[9])));
  Docente = arrayBuf;
  DateTime fecha = rtc.now();				// funcion que devuelve fecha y horario en formato
  //Serial.print("Hola ");
  //Serial.println(Docente);
  GrabarSdkeypad();//INICIA PROCESO DE ESCRITURA EN LA SD
}
   
else {
      /*
      DateTime fecha = rtc.now();				// funcion que devuelve fecha y horario en formato
			  Serial.print(fecha.day());				// funcion que obtiene el dia de la fecha completa
      Serial.print("/");					// caracter barra como separador
      Serial.print(fecha.month());				// funcion que obtiene el mes de la fecha completa
      Serial.print("/");					// caracter barra como separador
      Serial.print(fecha.year());				// funcion que obtiene el año de la fecha completa
      Serial.print(" ");					// caracter espacio en blanco como separador
      Serial.print(fecha.hour());				// funcion que obtiene la hora de la fecha completa
      Serial.print(":");					// caracter dos puntos como separador
      Serial.print(fecha.minute());				// funcion que obtiene los minutos de la fecha completa
      Serial.print(":");					// caracter dos puntos como separador
      Serial.print(fecha.second());			// funcion que obtiene los segundos de la fecha completa
      Serial.print("\t");         // imprime un espacio de tabulacion
      */
      Serial.println("Contraseña Incorrecta"); // si retorna verdadero muestra texto bienvenida
      BuzzerE();
       }
INDICE = 0;

}
}

void GrabarSdkeypad(){
digitalWrite(CS_SD,LOW); // Enables SD card chip select pin
myFile=SD.open("DATA.txt", FILE_WRITE);
if (myFile) {
delay(300);
//myFile.print(CLAVE);
//myFile.print(", ");
DateTime now = rtc.now();
myFile.print(now.year(), DEC);
myFile.print('/');
myFile.print(now.month(), DEC);
myFile.print('/');
myFile.print(now.day(), DEC);
myFile.print(',');
myFile.print(now.hour(), DEC);
myFile.print(':');
myFile.print(now.minute(), DEC);
myFile.print(':');
myFile.print(now.second(), DEC);
myFile.print(',');
myFile.print(Docente); //Nomre del docente
myFile.print(',');
myFile.println("Acceso mediante teclado numerico");
/*
Serial.print("Clave: ");
Serial.print(CLAVE);
Serial.print("\t"); // imprime un espacio de tabulacion
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print("\t"); // imprime un espacio de tabulacion
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.print("\t"); // imprime un espacio de tabulacion
Serial.println(Docente); //Muestra el nombre del docente
*/
Serial.println("sucessfully written on SD card");
delay(300);
myFile.close();
Buzzer();
}
else {
Serial.println("error opening data.txt");
BuzzerE();
}
digitalWrite(CS_SD,HIGH); // Disables SD card chip select pin
}

Moderador:
Por favor, lee las Normas del foro
En toda sección del foro, el primer hilo justamente son las normas.
Edita tu título, usa uno que no tenga justamente lo que se considera un título inútil.
Ver en las normas punto 5 sobre como poner títulos adecuados.
También debes editar tu código usando etiquetas.
Si no luce bien, ve a edición, luego selecciona todo el código que has publicado, lo cortas y click en (<CODE/>)



Y ahora lo mas importante!
No respondas antes de seguir las indicaciones que te he dado.

Y cuál es la pregunta?

Hola
Un par de consejos

Este array se puede poner en un PROGMEM y ganar 80 bytes en este:

No tiene sentido almacenar muchas instancias de la misma cadena en la PROGMEM

deje solo una cadena y utilícela donde la necesite

todo eso en vez de usar string puedes usar tipo de datos word que además será bastante más rápido la comparación y ocupará 2/5 de lo que ocupa ahora.
Deberías formatear y publicar el código correctamente, no hay quien lo lea
Saludos

Si en las cadenas fijas añades F() pasan a al flash y ahorras también algo.
Serial.println(F("No te conozco"));