You won't save thousands of bytes, but every bit counts.
More here:
mcp.pinMode(0, INPUT); //pin 10 on Expander
mcp.pinMode(1, INPUT); //pin 11 on Expander
mcp.pinMode(2, INPUT); //pin 12 on Expander
mcp.pinMode(3, INPUT); //pin 13 on Expander
mcp.pullUp(0, HIGH); // turn on a 100K pullup internally
mcp.pullUp(1, HIGH); // turn on a 100K pullup internally
mcp.pullUp(2, HIGH); // turn on a 100K pullup internally
mcp.pullUp(3, HIGH); // turn on a 100K pullup internally
mcp.pinMode(4, OUTPUT); //pin 14 on Expander
mcp.pinMode(5, OUTPUT); //pin 15 on Expander
mcp.pinMode(6, OUTPUT); //pin 16 on Expander
mcp.pinMode(7, OUTPUT); //pin 17 on Expander
mcp.digitalWrite(4, HIGH);
mcp.digitalWrite(5, HIGH);
mcp.digitalWrite(6, HIGH);
mcp.digitalWrite(7, HIGH);
Also, how large do these get?
int CarNumber = 1;
int condition = 0;
int OldCondition = 0;
int RxCar = 0;
int RxSpeed = 0;
int RxCondition = 0;
int RxOldCondition = 0;
If they can fit into a byte, use that. Generating code for 1-byte arithmetic often uses less space than larger data types.
tft.setCursor(25, 0);
tft.print(GPS.latitude);
tft.print(GPS.lat);
tft.setCursor(25, 8);
tft.print(GPS.longitude, 4);
tft.print(GPS.lon);
If space is tight I would be making a function that sets the cursor and then prints some text. Saves you repeating a lot of stuff.
tft.setTextColor(RED);
tft.println("Lat:");
tft.println("Lon:");
tft.println("Sat:");
tft.println("kph:");
tft.println("Alt:");
Will this work?
tft.setTextColor(RED);
tft.println("Lat:\nLon:\nSat:\nkph:\nAlt:");