Analysis of per-library memory usage

If you don't need the Serial library in the final product, you can omit that.
I use a "DEBUG" define that uses the Serial library only during debugging.
You could also use a common buffer, and use it temporary for many things.

Carefully read your code again, and move as much strings and data to flash memory as possible.
For example this: const char text[] = "Hello";
That uses ram, since it is copied from flash memory to ram during startup.
Also this: Serial.println("Hello");
That uses also the string "Hello" in ram.

For the libraries, you have to read the source code.