I will give you just a crude idea using WatershedComponents. That function can find the "ridge" between so called "catchment basins". You have to read up on that to understand. Taht "ridge" is your percolation path. It can also be for example a path in a maze. Alternatively, for general education for percolation coding, take a look at Finding a percolation path, Wolfram Demos, and NKS Book.
So let's go with WatershedComponents now. Your code a bit adjusted for around a percolation threshold:
L = 0.1;
n = 900;
SeedRandom[1]
centers = RandomReal[{0, 1}, {n, 2}];
? = RandomVariate[NormalDistribution[?/2, (1/2.3548)*?/4], n];
stickend1 = centers + Transpose[L {Cos[?], Sin[?]}/2];
stickend2 = centers - Transpose[L {Cos[?], Sin[?]}/2];
lines = Map[Line, Transpose[{stickend1, stickend2}]];
i = Binarize[ColorNegate[Graphics[{Thickness[.0], lines}, PlotRangePadding -> -.02]]]

Now you can find all the ridges, - those are 0-value components spanning the outer boundaries of the catchment basins:
Colorize[MorphologicalComponents[
WatershedComponents[i, CornerNeighbors -> True] /. {0 -> 1, x_Integer /; x > 0 -> 0}]]

For percolating cluster you select the largest one:
path = SelectComponents[MorphologicalComponents[
WatershedComponents[i, CornerNeighbors -> True] /. {0 -> 1, x_Integer /; x > 0 -> 0}],
"Count", -1] // Image

And you can highlight it on the original image too:
HighlightImage[i, path, Method -> {"Boundary", 2}]
