Help with integrating lcd

Im have a weird problem, I want to add an LCD to my project but when I add even just the #include <LiquidCrystal_I2C.h> the RFID uid outputs blank

#include <SPI.h>
#include <MFRC522.h>
#include <IRremote.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define SS_PIN 10
#define RST_PIN 9
#define RECV_PIN 2
#define BUZZER_PIN 7

MFRC522 rfid(SS_PIN, RST_PIN);

LiquidCrystal_I2C lcd(0x27, 16, 2); 

int questionNum = -1;

// Array of known RFID UIDs (in uppercase hexadecimal, 8 characters long)
String RFID_codes[] = {
  "C5BBB8C8", "2A2D27D2", "75BBE4C8", "75D92DC8", "2A4AB3D2", "2A29FBD2", "952A4AC8", "759B4BC8", "2A3BC1D2", "C6F6DCA7",
  "63D756A9", "6389ABA9", "C31357A9", "634594A9", "7389ABA9", "73DF89A9", "43E694A9", "B37B9BA9", "E35E9CA9", "E3F688A9",
  "63DE52A9", "03DA4E96", "53D258A9", "53D277A9", "73AAAB95", "934763A9", "83C662A9", "43A8BC95", "A36692A9", "238F4E96",
  "43A54E96", "A3C9D095", "9334F995", "F357DD95", "B34D1196", "838FF895", "0B3B1796", "B3914C96", "DEFFECTIVE", "DEFFECTIVE2"
};

// Array of corresponding question numbers (1 to 40)
byte question[] = {
  1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
  11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
  31, 32, 33, 34, 35, 36, 37, 38, 39, 40
};

const int totalCards = 40;

void setup(){
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  IrReceiver.begin(RECV_PIN); 
  lcd.init();
  lcd.backlight();
  showIdle();
}

void loop(){
  questionNum = checkIRremote();
  Serial.println(questionNum);

  String uid = checkRFID();
  for (int i = 0; i < totalCards; i++) {
    if (questionNum == question[i]) {
      if (uid == RFID_codes[i]) {
        successBeep();
        Serial.println("CORRECT");
        showCorrect();
      } else {
        wrongBeep();
        Serial.println("INCORRECT");
        showIncorrect();
      }
    }
  }
}

int checkIRremote () {
  int enteredNumber = 0;
  bool numberComplete = false;

  while (!numberComplete) {
    if (IrReceiver.decode()) {
      enteringBeep();
      switch (IrReceiver.decodedIRData.decodedRawData) {
        // IR codes for digits 1-9, 0
        case 3910598400: enteredNumber = enteredNumber * 10 + 1; break;
        case 3860463360: enteredNumber = enteredNumber * 10 + 2; break;
        case 4061003520: enteredNumber = enteredNumber * 10 + 3; break;
        case 4077715200: enteredNumber = enteredNumber * 10 + 4; break;
        case 3877175040: enteredNumber = enteredNumber * 10 + 5; break;
        case 2707357440: enteredNumber = enteredNumber * 10 + 6; break;
        case 4144561920: enteredNumber = enteredNumber * 10 + 7; break;
        case 3810328320: enteredNumber = enteredNumber * 10 + 8; break;
        case 2774204160: enteredNumber = enteredNumber * 10 + 9; break;
        case 2907897600: enteredNumber = enteredNumber * 10 + 0; break;

        // Code for "OK" or "Enter"
        case 3208707840: 
          if (enteredNumber > 0 && enteredNumber <= totalCards) {
             numberComplete = true; 
          } else {
             // Invalid number entered, reset
             enteredNumber = 0;
             Serial.println("Invalid question number.");
          }
          break;

        // Codes for "Clear" or "Back"
        case 3175284480:
        case 3041591040: 
          enteredNumber = 0; 
          Serial.println("Deleting...");
          break;
        default: 
          // ignore unknown buttons
          break;
      }

      // reset if number exceeds 40 (maximum allowed)
      if (enteredNumber > 40) {
        Serial.println("Number over 40, resetting...");
        enteredNumber = 0;
      }

      IrReceiver.resume(); // ready for next IR input
    }
  }

  return enteredNumber;
}

String checkRFID() {
  String uid = "";
  while (true) {
    if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
      for (byte i = 0; i < rfid.uid.size; i++) {
        uid += String(rfid.uid.uidByte[i], HEX);
      }
      uid.toUpperCase();

      Serial.print("UID: ");
      Serial.println(uid);

      // Stop communication
      rfid.PICC_HaltA();
      rfid.PCD_StopCrypto1();

      // Wait until card is removed to allow next scan
      while (rfid.PICC_IsNewCardPresent()) {
        // do nothing, just wait for removal
      }
      return uid;
    }
  }
}

// Buzzer Functions
void successBeep() {
  IrReceiver.stop();
  tone(BUZZER_PIN, 1000, 150);
  delay(150);
  tone(BUZZER_PIN, 1500, 150);
  delay(150);
  noTone(BUZZER_PIN);
  IrReceiver.begin(RECV_PIN);
}

void wrongBeep() {
  IrReceiver.stop();
  tone(BUZZER_PIN, 400, 600);
  delay(600);
  noTone(BUZZER_PIN);
  IrReceiver.begin(RECV_PIN);
}

void enteringBeep(){
  IrReceiver.stop();
  tone(BUZZER_PIN, 1000, 150);
  delay(150);
  noTone(BUZZER_PIN);
  IrReceiver.begin(RECV_PIN);
}
void errorBeep() {
  IrReceiver.stop();
  for (int i = 0; i < 3; i++) {
    tone(BUZZER_PIN, 500, 150);
    delay(500);
  }
  noTone(BUZZER_PIN);
  IrReceiver.begin(RECV_PIN);
}

// LCD Functions
void showIdle(){
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Enter Question");
  lcd.setCursor(2, 1);
  lcd.print("Using Remote");
}

void showCorrect(){
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print(String("Question: " + questionNum));
  lcd.setCursor(4, 1);
  lcd.print("CORRECT");
}

void showIncorrect(){
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print(String("Question: " + questionNum));
  lcd.setCursor(3, 1);
  lcd.print("INCORRECT");
}

void showQuestionEntering(int num){
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print(String("Question: " + num));
  lcd.setCursor(3, 1);
  lcd.print("PRESS 'OK'");
}

void showQuestion(){
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print(String("Question: " + questionNum));
  lcd.setCursor(2, 1);
  lcd.print("PLACE ANSWER");
}

Since you didn't mention which board you were using, I'll just assume that it's a Uno R3, classic Nano, or some other 328P based board with extremely limited RAM, point out that your sketch starts with only a couple of hundred bytes for local variables, stack space, any runtime library allocations, etc., and that your sketch will rapidly deplete that limited amount with all the String operations it performs. No RAM left: sketch doesn't work.

Global variables use 1784 bytes (87%) of dynamic memory, leaving 264 bytes for local variables. Maximum is 2048 bytes.

You have all kinds of string literals that could be moved out of RAM by using the F() macro.

You could avoid heap fragmentation entirely by forgoing String objects and using char arrays.

And if nothing else, you'll want to look into what String(rfid.uid.uidByte[i], HEX) outputs when the value is less than 10 hex.

And you should really turn your compiler warnings to ALL. Things like

  lcd.print(String("Question: " + questionNum));

don't do at all what you seem to think they do.