I2C y TX/RX juntos

se escapa a mi capacidad porque no tengo el hardware en las manos, de verdad haz algo más sencillo, haz sólo la pantalla sin nada más y prueba en otros pines además de esos

Tu problema tiene que ver con los tiempos de la pantalla y lo que debes esperar para leer el MP3.
Cuando lo haces individualmente este problema no existe porque esta dedicado a las tareas conocidas pero cuando los mezclas los tiempos consumidos por unos afectan a otros.
Lo mejor es como creo haberte dicho, usar una máquina de estados o mas simplemente limitar la presentación en pantalla a algo cada X mseg

Veamos este intento y no veo la parte de MP3, donde esta?

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"             // Librería para el módulo RTC
#include <SoftwareSerial.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//Objeto reloj RTC
RTC_DS3231 miReloj;

// Objeto MP3
#define RX 10         // Módulo MP3
#define TX 11         // Módulo MP3
SoftwareSerial DFPlayerSerial(RX, TX);

#define INTERVALO 1000UL

int prueba = 25;
int hora, minuto, segundo, dia, mes, ano;

float temperatura;
String monthsNames[13] = {"", "ene", "feb", "mar", "abr", "may", "jun", "jul","ago","sep","oct","nov","dic" };
String nombreMes;

void setup() {
	Serial.begin(9600);

	// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
	if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
		Serial.println(F("SSD1306 allocation failed"));
	for(;; // Don't proceed, loop forever
	}

	// Show initial display buffer contents on the screen --
	// the library initializes this with an Adafruit splash screen.
	display.display();
	delay(2000);
}

void loop() {
	int secAnt;
	
	/* Obtener la fecha actual */
	DateTime now = miReloj.now();
	segundo = now.second();
	
	if (segundo != secAnt) { // chequeado una vez x segundo
		hora = now.hour();
		minuto = now.minute();	
		dia = now.day();
		mes = now.month();
		nombreMes = monthsNames[mes];
		ano = now.year();	
		temperatura = miReloj.getTemperature();
	}

	if (millis() - tiempoOLED > INTERVALO) {
		showOled();
	}

}  /// ---- OJO A ESTO

void showOled() {
	char buffer[30];
	
	display.clearDisplay();
	display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
	display.setTextColor(SSD1306_WHITE);        // Draw white text

	display.setCursor(30,5);
	display.setTextSize(1);

	sprintf(buffer, "%d.%s.%d", dia, nombresMes, ano)
	display.println(buffer);

	display.setCursor(18,20);
	display.setTextSize(2);
	sprintf(buffer, "%2d:%2d:%2d", hora, minuto, segundo)
	display.println(buffer);

	display.setCursor(5,45);
	display.setTextSize(1);
	display.print ("Temperatura: ");
	display.print (temperatura);
	display.println (" C");

	display.display();
}

A la pucha @gatul, no era la memoria, era el tiempo, muy buena @surbyte

Siempre lo es y no me las doy de nada.
Siempre lo que falla al unir programas es justamente eso, lo dedicado que esta el código en un loop y al compartir tiempo con otro ya comienza a fallar.
Ademas como la pantalla insume mucho tiempo, te asustarías de ver los mseg que consume borrar o mejor dicho display.clearDisplay();, dicho sea de paso no hace falta cuando usas sprintf usar el borrado de pantalla y eso acelera mucho su refrezco.
Otro procedimiento caro en tiempo es el cambio de fuente o fonts. No abusar con ello.
Es preferible imprimir en pantalla todo lo que corresponda a tamaño 1 y luego lo que corresponda a tamaño 2 pero no ir cambiando entre uno y otro.
Si no me creen pongan micros() y hablemos de tiempos.

Ok, si cuando me meta con la mía ya molestaré con el tema, porque desde luego quiero algo bien complicado con tamaños diferentes de fuentes y gráficos, menos mal que para mí el tiempo no es un problema a la hora de mostrar, sólo en el sensor

Ahora entiendo el problema y por eso dice que cuando lo quita vuelve a funcionar el OLED.
Nos olvidamos de lo básico.
La pantalla OLED que interfaz tiene? NO es I2C, tal vez sea I2C la parte del Touch Screen pero la pantalla debiera ser SPI.
Ahora corroboro.
Entonces si es SPI usa 10, 11, 12 y 13 como pines y cuando agrega el SoftwareSerial con 10, 11 se cuelga.
Podría sin embargo usarlos cuando el OLED no este activo porque de hecho es posible.
Para mi no es buena idea, habiando tantos otros pines, mejor usar aquellos que no esten comprometidos.
Incluso alguno AX (analógico) puede usarse para tal sin considerar A4 y A5 y recordando que en el NANO A6 y A7 no puede usarse mas que para entradas analógicas.

Ahora chequeo y confirmo si estoy o no en lo cierto.

NOTA 1: En el código hay repetición de librerías, no entiendo por qué ni para qué?

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Eliminar las que estan debajo de RTClib.h.

NOTA 2: confirmado es SPI o I2C pero en el código observen su comienzo

#include <SPI.h>   // esta es para los pines 10, 11, 12, y 13
#include <Wire.h>  // esta es la interfaz I2C para A4 y A5

Una debe eliminarse
Si dices usar la I2C elimina la primera y entonces el SoftwareSerial no tendría que darte problemas.
Si usas SPI, entonces elige otros pines.