Render arrays are rendered by the renderer service (RendererInterface), which traverses the array and recursively renders each level. Each level of the array can have one or more elements, which can be two types--properties and children. The properties are the one whose keys are preceded by a # sign, whereas children are the ones which are not. The children can be themselves an array with properties and children. However, each level needs to have at least one property in order to be considered a level because it is responsible for telling the render system how that level needs to be rendered. As such, property names are specific to the Render API and to the actual thing they need to render while the names of children can be flexible. In addition to these two types (yes, I lied, there can be more than two), we can also have the variables defined by a theme hook, which are also preceded by the # sign. They are not properties per se, but are known by the theme system because they have been registered.
There are many properties the Render API uses to process a render array. Some of them are quite important, such as #cache and #attached. However, there are a few that are mandatory in order for a render array to make sense, in that they define their core responsibility. The following are the properties from among which each render array needs to have at least one.