You do it with nested loops:
for a in lista :
for b in listb :
for c in listc :
add (a + b + c) to output
If you don't know how many of these arrays are given to you, in a list say, then you will need to use recursion to in effect build this nested loops structure.
In a pattern-matching equational pseudocode,
combine( [lista, ...lists] ) = for a in lista: go( [a], lists )
go( abc, [listd, ...lists] ) = for d in listd: go( abc+[d], lists)
go( abcd, [] ) = ....handle the combination abcd....
Handle the edge cases, to make it work.
This can be implemented with indexing/pointer juggling to make it efficient, in C-like languages, without allocating too much of an extra memory (except for the output of course).
This approach is known as recursive-backtracking.
Creating an interim structure to produce the result will grow very large very fast -- the number of combinations is in fact exponential. With this approach you get to do the work only once inside the most nested loop.
P.S. More links to explore: 1, 2, 3, 4, 5, 6, 7...