The explanation is that Manipulate only reacts to changes of variables that appear literally in its body expression (the first argument). But in
Manipulate[Plot[s[[1]],{a,1,4}],{b,1,5},{c,1,5}]
the variables b and c don't appear in Plot[s[[1]],{a,1,4}], so the display isn't updated when they change.
This is a bit of a gotcha and hence it's described as a Possible Issue in the Manipulate documentation.
So your suggestion of introducing a function s2[a_, b_, c_] is the right idea. You might just want to change its definition to
s2[a_, b_, c_] := Module[{x}, x /. Solve[a x^2 + b x + c == 0, x][[1]]]
i.e. (1) localize the variable x using Module and (2) use := (SetDelayed) to defer evaluation of the right-hand side until the function is actually called (which is usually what you want when defining functions). Your suggestions works just fine as-is, but there will be surprises if you ever redefine a, b, c or x globally. By localizing variables, your code remains self-contained and isolated from global changes. That being said, sometimes it can be beneficial to solve an equation symbolically ahead of time (deliberately relying on global symbols such as a, b, c) and substitute symbols for numeric values later.