If you want to preserve the ordering of the input list, you need to reverse
the accumulator before return:

do_work([], Acc) ->
lists:reverse(Acc);

A question that comes up (in this case on
#erlang
today) is how well
lists:reverse/1 performs:
when should we reach for another data structure?

Because this pattern is so common,
lists:reverse/2,
which lists:reverse/1 is written in terms of, is a BIF:
definition in C
(note that a pile of other list functions are defined in C in the same file).

This means it should run pretty fast. The
Erlang efficiency guide
mentions it in the context of tail recursion, but urges us to measure.

Some log scales here, but as you can see, our list needs to be 100,000 elements
before we hit 10ms average on this system: assuming we're doing something
interesting when we process each list element, lists:reverse/1 is unlikely
to dominate our runtime. Besides, since we mostly work with much smaller
lists in real programs, this is definitely in the realm of "don't worry".

It's not super-scientific, but the simple answer to when to reach for something
other than a list appears to be "not quickly." :o) Good luck, and measure:
even naive measurement beats guessing.