Consider
[
"ABCD"
"EFGH"
"IJKL"
]
To obtain the main diagonal and the diagonals above it, we can shift out the first char of the second row and the first two of the third:
[
"ABCD"
"FGH"
"KL"
]
Note that all columns correspond to a diagonal, so "zipping" the array (i.e., transposing rows and columns) will yield an array containing the aforementioned four diagonals:
[
"AFK"
"BGL"
"CH"
"D"
]
We're still missing the diagonals below the main diagonal.
If we zip A itself and repeat the above process, we'll obtain an array containing the main diagonal and all diagonals below it. All that's left it to compute the set union of both arrays.
Putting it all together:
[.zip]{:A,,{.A=>}%zip}/|
[.zip]{ }/ # For the original array and it's transpose, do the following:
:A # Store the array in A.
,,{ }% # For each I in [ 0 1 ... len(A) ], do the following:
.A=> # Push A[I] and shift out its first I characters.
zip # Transpose the resulting array.
| # Perform set union.
Try it online.
Finally, if we only need the diagonals because we're searching for a string inside them (like in the Word Search Puzzle, which I assume inspired this question), a "less clean" approach might also be suitable.
You can use
..,n**\.0=,\,+)/zip
to obtain all diagonals, plus some unnecessary linefeed characters.
I've explained the process in detail in this answer.
Try it online.