What are the traditional ways to optimize program memory usage?
What are the generally practiced methods for the optimization program
memory usage?

First, note you are searching for ways to lower SRAM memory. This contains global (variable) memory and heap space (dynamic memory + stack memory).

Avoid memory gaps, by not using dynamic memory (with free/malloc/new).
Avoid using the String class.
Avoid global memory in SRAM by using PROGMEM, F(..) if possible.
Use the smallest variable size (e.g. uint8_t instead of int).
Store arrays of booleans into bits (8 booleans per byte).
Use bit flags if applicable.
Use some compressed type of memory internally (affects performance), e.g. if you have many 6 bit values to store, store them not in separate bytes but use 6 bytes for 8 times 6 bit values).
Avoid passing arrays by value.
Avoid a deep call stack with many (big) variables. Note this affects your design, so use it as a last resort.
If you need a calculatable table, calculate each value instead of storing it as a table.
Do not use longer arrays than needed, and think about reasonable maximum array sizes otherwise (see hcheung's comment below).
(this is not a complete list).


Is there any difference in memory usage if the variable is declared
globally or locally.

Yes, local variables are added to the stack, but are removed after the function ends, global variables stay (but are only created once).
Note that variables on the stack (and also dynamic memory) are NOT taken into account in the memory calculated in the warning message during compiling.

Will it matter what the control statement/selection statements are
(like if, switch )

No, this will only affect the program memory.

Usage of Serial monitor. Serial.print()

Probably yes, the serial monitor probably reserves (quite?) some memory as a buffer.

Low memory available, stability problems may occur.
How bad are these warnings?

How bad it is, depends on how much memory is used which is not calculated, which is dynamic memory, and stack memory.
You can calculate it manually (which can be quite cumbersome for a big program), you can also use the GitHub library for this:
Arduino MemoryFree
If you know how much heap memory you use worst case, than add it to the calculated global variables memory. If this is less than your maximum available SRAM memory, you are safe.