Apply ToString to a list of variables

In addition to Mr.Wizard's answer here is a collection of other possibilities:

data1 = {1, 1};
data2 = {2, 2};
datalist := {data1, data2};

ToString /@ Map[HoldForm, OwnValues[datalist], {3}][[1, 2]]
ToString /@ Map[Unevaluated, OwnValues[datalist], {3}][[1, 2]]
ToString /@ Thread[HoldForm[datalist] /. OwnValues[datalist]]
ToString /@ Thread[Extract[OwnValues[datalist], {1, 2}, HoldForm]]
ToString /@ Thread[Extract[OwnValues[datalist], {1, 2}, Unevaluated]]
ToString /@ Thread[Rest@Level[OwnValues[datalist], {2}, HoldForm]]
ToString /@ Thread[Rest@Level[OwnValues[datalist], {2}, Unevaluated]]
Unevaluated[Block[datalist, ToString /@ datalist]] /. OwnValues[datalist]
Cases[OwnValues[datalist], s_ :> Block[{s}, ToString@s], {3}] // Rest
Cases[OwnValues[datalist], s : {___} :> Block[s, ToString /@ s], {2}][[1]]
FirstCase[OwnValues[datalist], s : {__} :> Block[s, ToString /@ s], {}, {2}]
Cases[OwnValues[datalist], s : {___} :> ToString /@ Thread[HoldForm@s], {2}][[1]]
FirstCase[OwnValues[datalist], s : {__} :> ToString /@ Thread[HoldForm@s], {}, {2}]
{"data1", "data2"}

{"data1", "data2"}

{"data1", "data2"}

{"data1", "data2"}

{"data1", "data2"}

{"data1", "data2"}

{"data1", "data2"}

{"data1", "data2"}

{"data1", "data2"}

{"data1", "data2"}

{"data1", "data2"}

{"data1", "data2"}

{"data1", "data2"}

All the above methods work correctly when datalist is empty:

datalist := {};
ToString /@ Map[HoldForm, OwnValues[datalist], {-1}][[1, 2]]
{}

You're going to first need to hold {data1,data2} unevaluated in some way; either define it first, use SetDelayed (short form :=), or use Hold. I choose :=.

data1 = {1, 1};
data2 = {2, 2};
datalist := {data1, data2};

Cases[OwnValues[datalist], x_ :> ToString@Unevaluated@x, {3}] // Rest
{"data1", "data2"}

Or using my step function:

Cases[step[datalist], x_ :> ToString@Unevaluated@x, {2}]
{"data1", "data2"}