1) Adding more memory to the SGA may improve performance as more blocks can be held in the buffer cache. This will allow future block reads to come from memory, thereby improving performance. This relies very much on similar blocks being requested repeatedly, like you get in OLTP system. If each query is pulling back unique rows, then adding memory to the SGA will not necessarily improve performance. If the extra memory is taken up in the shared pool, holding lots of statement with literals, then the extra SGA will be of no benefit.
2) Are they using literals because they are too lazy to use bind variables, or was it a concious decision? It is very common for data warehouses to use lots of literals because each statement is unique and they do not expect SQL reuse. Adding bind variables in this case would not help SQL reuse and may reduce performance because of the way the optimizer deals with bind variables.
If this is an OLTP system and they would like better SQL reuse, the cursor sharing can help, but you have to be careful about the affects of bind peeking. Some statements may perform worse, especially those with skewed data. You have to do a full system test to determine the affect of the change.
3) Sounds like the system is doing lots of hard parses of new SQL statements. Each hard parse requires a latch on the library cache, since the hard parse results in an amendment to the contents of the library cache, which gets reported as a concurrency wait.
The best place to get the latch information from is the AWR report, or statspack if you don't have the Diagnostics and Tuning Pack option.