First off, there are thousands of symbols, so it doesn’t seem practical to be inspecting them directly.
Second, many built-in symbols are ReadProtected, so you can’t really inspect them very closely. Even symbols that aren’t ReadProtected might still hide their implementation details.
Third, some symbols don’t have any definitions–they’re more like reserved symbols. E.g. \[FormalA]. And some others are interpreted differently in different situations. E.g. Automatic.
If you’re not actually wanting to inspect all built-in symbols, but instead want “to learn how to distinguish functions from non-functions”, then you need to be clear about what you mean by “function”. To the Wolfram Language, everything is an expression, and the Wolfram Language has a process for evaluating expressions that involves replacement rules. The concept of function is a mathematical one–the Wolfram Language can only give you some tools for modeling functions in code.
Here are two different ways you could model a function in WL:
(* Set/SetDelayed *)
(* This adds an element to DownValues *)
somefunc[x_, y_] := x + 3 y;
(* Function *)
(* This adds an elemnt to OwnValues, but that element is an expression
that will be applied to arguments when it appears as the head of an expression*)
otherfunc = Function[{x, y}, x + 3 y];
Are these both functions to you? It’s hard to find a property that will select these correctly. You can’t just say “if it has down-values then it’s a function”.
DownValues[somefunc]
(* {HoldPattern[somefunc[x_, y_]] :> x + 3 y} *)
DownValues[otherfunc]
(* {} *)
OwnValues[somefunc]
(* {} *)
OwnValues[otherfunc]
(* {HoldPattern[otherfunc] :> Function[{x, y}, x + 3 y]} *)
So, your question doesn’t really seem to be well-specified. What is it that you’re actually wanting to do or learn? Do you actually need a rigorous way to distinguish function from non-function, or is there some other way to achieve your objective?