Another solution making use of devtools::session_info() which can be copied straight into an R markdown file (Rmd):
R environment
<!-- TABLE TITLE: -->
(ref:Reproducibility-SessionInfo-R-environment-title) R environment session info for reproducibility of results
\renewcommand{\arraystretch}{0.8} <!-- decrease line spacing for the table -->
```{r Reproducibility-SessionInfo-R-environment, echo=FALSE, message=FALSE, warning=FALSE, fig.align="center", out.width='100%', results='asis'}
library("devtools")
# library("knitr")
df_session_platform <- devtools::session_info()$platform %>% 
  unlist(.) %>% 
  as.data.frame(.) %>% 
  rownames_to_column(.)
colnames(df_session_platform) <- c("Setting", "Value")
kable(
  df_session_platform, 
  booktabs = T, 
  align = "l",
  caption = "(ref:Reproducibility-SessionInfo-R-environment-title)", # complete caption for main document
  caption.short = " " # "(ref:Reproducibility-SessionInfo-R-environment-caption)" # short caption for LoT
) %>% 
  kable_styling(full_width = F,
                latex_options = c(
                  "hold_position" # stop table floating
                ) 
  ) 
```
\renewcommand{\arraystretch}{1} <!-- reset row height/line spacing -->

Required Packages
<!-- TABLE TITLE: -->
(ref:Reproducibility-SessionInfo-R-packages-title) Package info for reproducibility of results
\renewcommand{\arraystretch}{0.6} <!-- decrease line spacing for the table -->
```{r Reproducibility-SessionInfo-R-packages, echo=FALSE, message=FALSE, warning=FALSE, fig.align="center", out.width='100%', results='asis'}
df_session_packages <- devtools::session_info()$packages %>% 
  as.data.frame(.) %>% 
  filter(attached == TRUE) %>% 
  dplyr::select(loadedversion, date) %>% 
  rownames_to_column
colnames(df_session_packages) <- c("Package", "Loaded version", "Date")
kable(
  df_session_packages, 
  booktabs = T, 
  align = "l",
  caption = "(ref:Reproducibility-SessionInfo-R-packages-title)", # complete caption for main document
  caption.short = " " # "(ref:Reproducibility-SessionInfo-R-packages-caption)" # short caption for LoT
) %>% 
  kable_styling(full_width = F,
                latex_options = c(
                  "hold_position" # stop table floating
                ) 
  ) 
```
\renewcommand{\arraystretch}{1} <!-- reset row height/line spacing -->

If one has loaded very many packages, one can split the table into several columns
credits go to @user2554330 and @RobertoScotti for their snippets to split tables provided to this SO Q.
```{r prepare multicolumn-table, echo=FALSE, message=FALSE, warning=FALSE}
colnames(df_session_packages) <- c("Package", "Loaded version", "Date")
rows <- seq_len(nrow(df_session_packages) %/% 2)
l_session_packages <- list(df_session_packages[rows,1:3],  
           matrix(numeric(), nrow=0, ncol=1),
           df_session_packages[-rows, 1:3])
```
Generate the table: for few packages vertically crunched on a portrait page
\renewcommand{\arraystretch}{0.8} <!-- decrease line spacing for the table -->
```{r Reproducibility-SessionInfo-R-packages, echo=FALSE, message=FALSE, warning=FALSE, fig.align="center", out.width='100%', results='asis'}
kable(
  l_session_packages, 
  row.names = T,
  booktabs = T, 
  align = "l",
  caption = table_caption, # complete caption for main document
  caption.short = table_caption_title # short caption for LoT
) 
```
\renewcommand{\arraystretch}{1} <!-- reset row height/line spacing -->
Generate the table: for very many packages on a landscape page
\begin{landscape}
```{r Reproducibility-SessionInfo-R-packages-lanscape, echo=FALSE, message=FALSE, warning=FALSE, fig.align="center", out.width='100%', results='asis'}
kable(
  l_session_packages, 
  row.names = T,
  booktabs = T, 
  align = "l",
  caption = table_caption, # complete caption for main document
  caption.short = table_caption_title # short caption for LoT
) 
```
\end{landscape}
Generate the table: for very many packages on a landscape page
\begin{landscape}
```{r Reproducibility-SessionInfo-R-MANY-packages-lanscape, echo=FALSE, message=FALSE, warning=FALSE, fig.align="center", out.width='100%', results='asis'}
# SOURCE: Roberto Scotti (StackOverflow)
# https://stackoverflow.com/questions/56445149/how-can-i-split-a-table-so-that-it-appears-side-by-side-in-r-markdown
split.print <- function(x, cols = 2, sects = 1, spaces = 1, caption = "", label = ""){
  if (cols < 1) stop("cols must be GT 1!")
  if (sects < 1) stop("sects must be GT 1!")
  rims <- nrow(x) %% sects
  nris <- (rep(nrow(x) %/% sects, sects) + c(rep(1, rims), rep(0, sects-rims))) %>%
    cumsum() %>%
    c(0, .)
  for(s in 1:sects){
    xs <- x[(nris[s]+1):nris[s+1], ]
    rimc <- nrow(xs) %% cols
    nric <- (rep(nrow(xs) %/% cols, cols) + c(rep(1, rimc), rep(0, cols-rimc))) %>%
      cumsum() %>%
      c(0, .)
    lst <- NULL
    spc <- NULL
    for(sp in 1:spaces) spc <- c(spc, list(matrix(numeric(), nrow=0, ncol=1)))
    for(c in 1:cols){
      lst <- c(lst, list(xs[(nric[c]+1):nric[c+1], ]))
      if (cols > 1 & c < cols) lst <- c(lst, spc)
    }
    kable(lst,
          row.names = T,
          caption = ifelse(sects == 1, caption, paste0(caption, " (", s, "/", sects, ")")),
          #label = "tables", format = "latex",
          booktabs = TRUE) %>%
      kable_styling(latex_options = "hold_position") %>%
      print()
  }
}
df_session_packages %>%
  dplyr::select(1:3) %>%
  split.print(cols = 2, sects = 1, caption = "multi page table")
```
\end{landscape}
