You have to sacrifice something, but it depends on your preferences what you want to keep and what you want to give up. Let's assume you don't want to sacrifice being able to use assignments such as w=3, then you may have to give up using {...} as a wrapper grouping the names of the variables together. You could then define a new wrapper myList to be used instead of {...}:
w = 3; g = 4;
myList[x__] := {ReleaseHold[HoldForm /@ Hold[x]]}
SetAttributes[myList, HoldAll]
myList[w, g][[2]]
g
This is done by wrapping all elements of myList in HoldForm. You can retrieve the values of these held expressions by applying ReleaseHold to them.
Edit
To address the question about DumpSave, we have to modify the strategy a little:
myList[x__] := {ReleaseHold[Unevaluated /@ Hold[x]]}
Table[
DumpSave["ex" <> ToString[i] <> ".mx", #] &[myList[w, g][[i]]], {i,
1, 2}]
(* ==> {{3}, {4}} *)
Here, I replaced HoldForm by Unevaluated in myList, so that the symbols g and w are now wrapped by it and will also print with that wrapper. The list of DumpSave commands in the Table then can take these unevaluated arguments as input. However, since DumpSave itself has attribute HoldRest, it wouldn't evaluate these wrappers either. So instead I feed them into DumpSave using the anonymous function ... #]& [..] which doesn't obey the HoldRest attribute.
Clear[w, g]; (w + g)/. {w->1, g->2}. So if you want the unevaluated symbol form, you can always write{w, g}[[2]]to getg. – István Zachar Mar 27 '13 at 17:57