This is not meant to be a definitive treatise on how to optimize your code - there are libraries full of books on the subject. What is presented here are just some simple tips to help harvest the low-hanging fruit.
If your project is a mash-up of code from several sources, chances are there are parts that are not getting used and can be eliminated to save space.
- Unused Libraries - Are all the #include libraries actually used?
- Unused Functions - Are all the functions actually being called?
- Unused Variables - Are all the variables actually being used?
- Unreachable Code - Are there conditional expressions which will never be true?
If you have the same sequence of code statements in two or more places, consider making a function out of them.
If space is really-really tight, you might consider eliminating the bootloader. This can save as much as 2K or 4K of Flash - depending on which bootloader you are currently using.
The downside of this is that you will need to load your code using an ISP programmer instead of via a standard USB cable.